/* 	
	Title: form

	Este archivo contiene la clase Form, que permite crear un formulario a partir de un div y una serie de fields
 	Conviene ver la documentación de Cell y Form antes.
 */

FORM_DEFAULT_CONTENTS =
{
	form:		function(title, content, footer)
	{
		var res = document.createElement("div");

		if(title)
			res.appendChild(title);

		if(content)
			res.appendChild(content);

		if(footer)
			res.appendChild(footer);
		
		return res;
	},

	title:		function(title, edit, erase)
	{
		return createElement({ type_node: "div", children: [ { type_node: "text", text: title }, edit, erase ] } );
	},

	footer:		function(submit)
	{
		return createElement({ type_node: "div", children: [ submit ] } );
	},

	group:		function(title, content, footer)
	{
		var res = document.createElement("div");

		if(title)
			res.appendChild(title);

		if(content)
			res.appendChild(content);

		if(title)
			res.appendChild(footer);
		
		return res;
	}
};

/* Constructor
 * Este constructor sólo requiere un div padre que lo contenga y las fields asociadas.
 */
function Form(parent_div, fields_data, rows_data, def_conf, fields_conf)
{
	this.parent_div  = parent_div;
	this.div_content = false;

	this.fields_data = fields_data;
	this.rows_data = rows_data;

	this.rows_div = document.createElement("div");

	this.fields = new Array;
	this.rows = new Array;
	this.new_row = false;

	this.def_conf = def_conf;
	
	this.settings = 
	{
		data:
		{
			title:			false,
			show_rows:		true,

			new_row:		false,
			new_row_func:	false
		},

		class_names:
		{
			title:			"",
			content:		"",
			footer:			""
		},

		contents:
		{
			form:			FORM_DEFAULT_CONTENTS.form,
			title:			FORM_DEFAULT_CONTENTS.title,
			footer:			FORM_DEFAULT_CONTENTS.footer,

		}
	}

	this.create();
	this.setup(def_conf, fields_conf);

}


Form.prototype = 
	{
		/* Crea el formulario
		 * Para ello crea una cell para cada field y le asigna el nombre de la field y un id único.
		 */
		create:	function()
		{
			var i = 0;
			if(this.fields_data)
			{
				for(var f in this.fields_data)
				{
					this.fields[i] = new Field(this.fields_data[f].name, this.fields_data[f].type, this.fields_data[f].len, this.fields_data[f].flags);

					i++;
				}
			}

			var i = 0;
			if(this.rows_data)
			{
				var row_div;
				for(var r in this.rows_data)
				{
					var values = new Array;
					for(var v in this.rows_data[r])
						values.push(this.rows_data[r][v]["value"]);

					row_div = document.createElement("div");
					this.rows[i] = new Row(row_div, values, this.fields);
					this.rows_div.appendChild(row_div);

					values = null;
					i++;
				}
			}

			row_div = document.createElement("div");
			this.new_row = new Row(row_div, false, this.fields, this);
			this.rows_div.appendChild(row_div);
		},


		setup:	function(def_conf, fields_conf)
		{	
			if(def_conf.fields)
			{
				for(var f in this.fields)
				{
					this.fields[f].setup(def_conf.fields);
				}
			} 

			if(def_conf.par || def_conf.impar)
			{
				var par = true;
				for(var f in this.fields)
				{
					if(par && def_conf.par)
						this.fields[f].setup(def_conf.par);
					else if(!par && def_conf.impar)
						this.fields[f].setup(def_conf.impar);

					par = !par;
				}
			}

			var i =  0;
			if(fields_conf)
			{
				for(var f in this.fields)
				{
					this.fields[f].setup(fields_conf[i]);

					i++;
				}
			}


			if(def_conf.form)
			{
				for(var lv1 in def_conf.form)
				{
					for(var lv2 in def_conf.form[lv1])
					{

						this.settings[lv1][lv2] = def_conf.form[lv1][lv2];
					}
				}
			}


			if(def_conf.row)
			{
				for(var r in this.rows)
				{
					this.rows[r].setup(def_conf.row);
				}
				this.new_row.setup(def_conf.row);
			}

			if(def_conf.new_row)
			{
				this.new_row.setup(def_conf.new_row);
			}
				
		},
		
		/* Esta función muestra todos los cells
		 * Para ello llama a cell.show de cada Cell. También crea un botón Submit.
		 * Por ahora dicho botón no hace nada especial, sólo cambia el modo de mostrar de IN a OUT.
		 * En la siguiente práctica seguramente tenga que actualizar la BD.
		 *
		 * type:	Es el modo que queremos mostrar cada cell (IN / OUT)
		 */
		show:	function(type)
		{
			var title = this.settings.contents.title(this.settings.data.title);
			title.className = this.settings.class_names.title;

			var footer = this.settings.contents.footer();
			footer.className = this.settings.class_names.footer;

			this.div_content = this.settings.contents.form(title, this.rows_div, footer);

			this.parent_div.appendChild(this.div_content);

			if(this.settings.data.show_rows)
			{
				for(var r in this.rows)
					this.rows[r].show(type);
			}

			if(this.settings.data.new_row)
				this.new_row.show("input");


		},

		// Crea una función de error de usuario asociada a la field indicada.
		setErrorFunc: function(fields, func, text)
		{
			var cells = new Array();
			if(fields.length)
			{
				var f;

				for(f in fields)
				{
					if(this.cells[fields[f]])
						cells.push(this.cells[fields[f]]);
				}

				for(f in fields)
				{
					if(this.fields[fields[f]])
						this.fields[fields[f]].setErrorFunc(cells, func, text);
				}

			}
		},

		addRow:		function(row)
		{
			if(this.settings.data.show_rows)
			{
				row.settings = new Row().settings;
				if(this.def_conf.row)
					row.setup(this.def_conf.row);

				row.parent_form = false;
			}
			else
			{
				row.destroy();
			}

			row_div = document.createElement("div");
			this.new_row = new Row(row_div, false, this.fields, this);
			this.rows_div.appendChild(row_div);

			if(this.def_conf.row)
				this.new_row.setup(this.def_conf.row);

			if(this.def_conf.new_row)
				this.new_row.setup(this.def_conf.new_row);

			this.new_row.show("input");

			if(this.settings.data.new_row_func)
				this.settings.data.new_row_func.call(this);
		},

			
			


		erase:		function()
		{
			while(this.parent_div.firstChild)
				this.parent_div.removeChild(this.parent_div.firstChild);
		}
	}

		

		

